package sqlgenerator

import (
	"fmt"
	"strings"
)

type baseGen struct {
	reserved Reserved
}

func (bd *baseGen) IsReserved(word string) bool {
	return bd.reserved.IsReserved(word)
}

func (bd *baseGen) QuoteExpr(sql string) string {
	return sql
	// return strings.ReplaceAll(sql, "\"", "\\\"")
}

func (bd *baseGen) CheckReserved(word string) string {
	return bd.reserved.CheckReserved(word)
}

func (bd *baseGen) Insert(sql *SQL) (string, []*SQLParam) {
	return fmt.Sprintf("INSERT INTO %s (%s) VALUES (%s)",
		bd.CheckReserved(sql.TableName),
		strings.Join(sql.Columns, ","),
		strings.Join(sql.ParamPlaceHolder, ",")), sql.Params
}

func (bd *baseGen) Update(sql *SQL) (string, []*SQLParam, []*SQLParam) {
	// quoter := bd.Dialect.Quoter()
	if sql.Where != "" {
		sqlStr := fmt.Sprintf("UPDATE %s SET %s WHERE %s",
			bd.CheckReserved(sql.TableName),
			strings.Join(sql.Columns, ","),
			sql.Where)
		return bd.QuoteExpr(sqlStr), sql.Params, sql.WhereParams
	}
	sqlStr := fmt.Sprintf("UPDATE %s SET %s",
		bd.CheckReserved(sql.TableName),
		strings.Join(sql.Columns, ","))
	return bd.QuoteExpr(sqlStr), sql.Params, nil
}
func (bd *baseGen) Delete(sql *SQL) (string, []*SQLParam) {
	// quoter := bd.Dialect.Quoter()
	if sql.Where != "" {
		sqlStr := fmt.Sprintf("DELETE FROM %s WHERE %s",
			bd.CheckReserved(sql.TableName),
			sql.Where)
		return bd.QuoteExpr(sqlStr), sql.WhereParams
	}
	sqlStr := fmt.Sprintf("DELETE FROM %s",
		bd.CheckReserved(sql.TableName))
	return bd.QuoteExpr(sqlStr), sql.Params
}

func (bd *baseGen) Query(sql *SQL) (string, []*SQLParam) {
	if sql.Where != "" {
		sqlStr := fmt.Sprintf("SELECT %s FROM %s WHERE %s %s",
			strings.Join(sql.Columns, ","),
			bd.CheckReserved(sql.TableName),
			sql.Where,
			sql.OrderAndGroup)
		return bd.QuoteExpr(sqlStr), sql.WhereParams
	}
	sqlStr := fmt.Sprintf("SELECT %s FROM %s %s",
		strings.Join(sql.Columns, ","),
		bd.CheckReserved(sql.TableName),
		sql.OrderAndGroup)
	return bd.QuoteExpr(sqlStr), sql.WhereParams
}

func (bd *baseGen) Truncate(sql *SQL) string {
	return fmt.Sprintf("truncate %s", sql.TableName)
}

func (bd *baseGen) IsParamDollar() bool {
	return false
}

func (bd *baseGen) IsReturnAutoincrPrimaryKeyUseQuery() bool {
	return false
}

func (bd *baseGen) GetParamTag() string {
	return "?"
}

func (bd *baseGen) replaceParams(sql, paramTag string) string {
	s := sql
	plen := len(paramTag)
	if plen > 0 {
		index := 0
		for {
			pindex := strings.Index(s, paramTag)
			if pindex < 0 {
				break
			}
			index++
			s = s[:pindex] + fmt.Sprintf("$%d", index) + s[pindex+plen:]
		}
	}
	return s
}
